package com.banmajio.config;

import java.io.IOException;
import java.lang.reflect.Field;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AnnotationTemplateProvider<T> implements BatchCopyHelper.ValueProvider<T> {
    private final Class<T> clazz;
    private final List<Field> fields;
    private final Map<String, DateTimeFormatter> formatters = new HashMap<>();

    public AnnotationTemplateProvider(Class<T> clazz) {
        this.clazz = clazz;
        this.fields = new ArrayList<>();

        // 收集所有带 @CopyField 注解且不忽略的字段
        for (Field field : clazz.getDeclaredFields()) {
            CopyField annotation = field.getAnnotation(CopyField.class);
            if (annotation != null && !annotation.ignore()) {
                field.setAccessible(true);
                fields.add(field);

                // 缓存日期格式化器
                if (!annotation.format().isEmpty()) {
                    formatters.put(field.getName(), DateTimeFormatter.ofPattern(annotation.format()));
                }
            }
        }
    }

    @Override
    public String formatLine(T item) {
        StringBuilder line = new StringBuilder();

        for (Field field : fields) {
            try {
                CopyField annotation = field.getAnnotation(CopyField.class);
                Object value = field.get(item);

                if (value == null) {
                    line.append("\\N\t"); // NULL 值用 \N 表示
                    continue;
                }

                // 处理特殊类型
                if (value instanceof LocalDateTime) {
                    DateTimeFormatter formatter = formatters.get(field.getName());
                    if (formatter != null) {
                        line.append(formatter.format((LocalDateTime) value)).append("\t");
                    } else {
                        line.append(value.toString()).append("\t");
                    }
                }
                // 可添加其他类型处理（如 BigDecimal、Date 等）
                else {
                    line.append(escapeCsvValue(value.toString())).append("\t");
                }
            } catch (Exception e) {
                // 出错时记录错误并设置为 NULL
                System.err.println("Error formatting field " + field.getName() + ": " + e.getMessage());
                line.append("\\N\t");
            }
        }

        // 移除最后一个制表符
        if (line.length() > 0) {
            line.setLength(line.length() - 1);
        }

        return line.toString();
    }

    /**
     * 转义 CSV 特殊字符
     */
    private String escapeCsvValue(String value) {
        if (value == null) return "\\N";

        return value
                .replace("\\", "\\\\")  // 转义反斜杠
                .replace("\t", "\\t")   // 转义制表符
                .replace("\n", "\\n");  // 转义换行符
    }

    /**
     * 获取数据库字段名列表（按注解顺序）
     */
    public List<String> getDatabaseFieldNames() {
        List<String> dbFieldNames = new ArrayList<>();

        for (Field field : fields) {
            CopyField annotation = field.getAnnotation(CopyField.class);
            String dbName = annotation.name().isEmpty() ? field.getName() : annotation.name();
            dbFieldNames.add(dbName);
        }

        return dbFieldNames;
    }
}
